/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
 * Generated on: 2020/08/26
 * Function description: PCI MSI interrupt initialization header file
 */

#ifndef PCIE_MSI_H
#define PCIE_MSI_H
#include "pcie_chip.h"

#define PCIE_MSI_DEBUG_PRINT(...)

#define PCIE0_MSI_ENHANCE_PROC      "pcie_msi"
#define PCIE0_MSI_ENHANCE_PROC_FILE "pcie0_msi_enhance"
#define PCIE1_MSI_ENHANCE_PROC_FILE "pcie1_msi_enhance"
#define PCIE2_MSI_ENHANCE_PROC_FILE "pcie2_msi_enhance"

#define PCIE_MSI_ENHANCE_PROC_LEN    (16)     /* proc setting interface, supports string length */

/* SMI */
#define MAX_MSI_IRQS                 (32)     /* single ep mode support 32 interrupt at most */

#define PCIE_CFG_HDR1                (0x004)  /* INTx interrupt control reg */
#define PCIE_MSI_CAP0                (0x050)  /* MSI interrupt control reg */
/* MSI msg write to SOC addr
 * low 32bit, must physical */
#define PCIE_MSI_ADDR_LO             (0x820)
/* MSI msg write to SOC addr
 * high 32bit, must physical */
#define PCIE_MSI_ADDR_HI             (0x824)
/* ep enable reg, base addr
 * bit higher means enable interrupt vector */
#define PCIE_MSI_INTR0_ENABLE        (0x828)
/* ep mask reg addr
 * bit higher means mask interrupt vector */
#define PCIE_MSI_INTR0_MASK          (0x82C)
/* ep status reg addr
 * bit hgihrt means interrupt cleared by write 1 */
#define PCIE_MSI_INTR0_STATUS        (0x830)
#define PCIE_MSI_INTX_ENABLE         (10)     /* INTx interrupt enable, control 16 bit */
#define PCIE_MSI_SMI_ENABLE          (16)     /* MSI interrupt enable, control 16 bit */

#define PCIE_MSI_EP_MAX_NUM          (8)      /* hisi SOC support at most 8 ep */
#define PCIE_MSI_EP_SHIFT            (12)     /* interval of EP cfg reg in each group (12 bits) */
/* qualcomm QCN9024 drviver, sub-driveris the status register value minus 16 */
#define PCIE_MSI_EP_INTERRUPT_SHIFT  (16)
#define PCIE_MSI_INTERURRPT_NUM_BASE (105)    /* PCIE MSI hardware interrupt start id */
#define MSI_INVALID_OPS              (32)     /* invalid interrupt id */
#define PCIE0_MSI_INTERURRPT_NUM_5182T (67)   /* 5182T PCIE0 MSI hardware interrupt id */
#define PCIE1_MSI_INTERURRPT_NUM_5182T (74)   /* 5182T PCIE1 MSI hardware interrupt id */
#define PCIE2_MSI_INTERURRPT_NUM_5182T (81)   /* 5182T PCIE2 MSI hardware interrupt id */
#define PCIE0_MSI_INTERURRPT_NUM_1156  (67)   /* 1156  PCIE0 MSI hardware interrupt id */
#define PCIE_MSI_INTERURRPT_NUM_INVALID 0     /* invalid MSI hardware interrupt id */

struct pcie_msi_enhance {
	uint32_t basic_irq;              /* sub-interrupr start irq */
	uint32_t wait_proc_irq;          /* sub-interrupt waiting for process */
	uint32_t msi_split_irq;          /* sub-interrupt core division split point */
};

/* definition of data of function pointer type */
typedef int (*pcie_irq_set_msi_desc_off)(uint32_t irq_base,
	uint32_t irq_offset, struct msi_desc *entry);

/* declared as external interface */
struct irq_domain *hal_pcie_init_msi_irq(struct pcie_info *info);
struct msi_controller *hal_msi_get_msi_ctrl(void);
void pcie_msi_create_enhance_proc(void);
uint32_t hal_msi_get_irq_num(uint32_t phy_num, uint32_t *irq_num);

#endif /* PCIE_MSI_H */
